#ifndef THREED_ELEMENTARY_GEOMETRY_TOOL_LIBRARY_H_
#define THREED_ELEMENTARY_GEOMETRY_TOOL_LIBRARY_H_

#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<Matrix/LB_Matrix.h>



#ifndef SIGN
#define SIGN(x) ((x>0)?1:((x<0)?-1:0))
#endif
#ifndef SAFE_SQRT
#define SAFE_SQRT(x) (x>=0?sqrt(x):0)
#endif
#ifndef SAFE_FREE
#define SAFE_FREE(x) if(x!=NULL){free(x);x=NULL;}
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifdef __cplusplus
extern "C" {
#endif

// return (a,b,c,d) where ax+by+cz+d=0 ,(a,b,c) is normalized vector
double*get_plane_equation_of_triangular_plane(double* tr1,double* tr2,double*tr3);

//@ p1 is a plane equation
//@ p2 is a plane equation
//return t* n+ p:: line equation
double* get_line_equation_from_2planes(double * p1,double *p2);

static inline double * get_line_equation_from_two_points(double*p1,double* p2 )
{
    double * re=(double*)malloc(sizeof(double)*6);
    re[0]=p2[0]-p1[0];re[1]=p2[1]-p1[1];re[2]=p2[2]-p1[2];
    if(!normalize(re,3))
    {
        free(re);
        return NULL;
    } 
    re[3]=p1[0];re[4]=p1[1];re[5]=p1[2];
    return re;
}


// @ l: the normalized line n1*t1+p1
// @ l1:the normalized line n2*t2+p2
// @ return the t1   


//l ,l1必须不同向
static inline double line_point_nearest_2_line(double* l,double* l1)
{
    double n1n2=inner_product(l,l1,3);
    double p1p2[3]={l[3]-l1[3],l[4]-l1[4],l[5]-l1[5]};
    return (n1n2* inner_product(p1p2,l1,3)-inner_product(p1p2,l,3))/(1-(n1n2)*(n1n2));
}


static inline double distance_from_point_to_line(double* p,double* l)
{
    double a[3]={p[0]-l[3],p[1]-l[4],p[2]-l[5]};
    double dis=a[0]*l[0]+a[1]*l[1]+a[2]*l[2];
    double dis1=a[0]*a[0]+a[1]*a[1]+a[2]*a[2]; 
    return SAFE_SQRT(dis1-dis*dis); 

}
//判断在同一平面上直线和线段是否相交
int is_line_intersecting_with_line_segment(double* l,double* v1,double *v2);

//判断在三维空间中两线段是否相交
int is_line_segment_intersecting_with_line_segment(double * v1,double* v2,double *vv1,double*vv2);

// double * line_intersection_with_polygon(double* l,double** poly ,int len)


// convex polygons 

//@return double [2][3];
// poly1 poly2 not in one plane(不在同一个平面上)
//保证poly1和poly2是凸的
//if no intersections return NULL
double ** get_intersection_points_from_two_polygons(double**poly1,int len1,double**poly2 ,int len2);
//return the triangle coordinate of p in p1 p2 p3
double* get_triangle_coordinate(double* p,double * p1,double*p2,double* p3 );

double compute_area_of_triangle(double* tri1,double* tri2,double* tri3);

#ifdef __cplusplus
}
#endif

#endif
